<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 

/*
| -------------------------------------------------------------------
| AuthenticatedController
| -------------------------------------------------------------------
| AuthenticatedController is a subclass of Controller.
|
| AuthenticatedController uses _remap to intercept method calls
| and determine if current user has access to Controller/Method pair.
|
|
*/

class AuthenticatedController extends CI_Controller {
 
    public function __construct()
    {
        parent::__construct();

        $this->config->load('config');
        $this->config->load('auth/AuthenticatedControllerConfig');
        $authenticatorclass = $this->config->item('authenticator');
        $this->load->library($authenticatorclass,'','authenticator');
		$this->load->library('session');
    }


    /**
     * _remap
     *
     * @return void
     * @author Doug Everly
     *
     * _remap is called for EVERY AuthenticatedController method
     * to check if access is permitted.
     *
     **/
    function _remap($method)
    {
        /**
         * Account is active
        **/
        if (!$this->_expired())
        {
            if ($this->_authorized($method))
            {
                /**
                 * proceed ...
                **/
                $this->$method();
            }
            else
            {
                /**
                 * otherwise access denied
                **/
                $this->_denied($method);
            }
        }
        /**
         * Account is expired
        **/
        else
        {
            $this->load->helper('url');
             $this->config->load('auth/AuthenticatedControllerConfig');
             $this->session->set_userdata('dest_url',  $this->uri->uri_string());
            redirect($this->config->item('auth_expired') . "?url=" . urlencode(current_url() . "?" . $_SERVER['QUERY_STRING']), 'refresh');
        }
    }

    // PAGE PARSING
    
    protected function _this_class()
    {
         return get_class($this);
    }
    
    protected function _expired()
    {
        if ($this->session->userdata('groups'))
        {
            return 0;
        }
        return 1;
    }
    
    /*    _authorized
     *
     *    Return the authorization boolean of web user to access
     *     Controller.
     *
     *
     */
    protected function _authorized($method = NULL)
    {
        if ($this->_can_access_class($this->_this_class()) && $this->_can_access_method_of_class($method, $this->_this_class()))
        {
            return 1;
        }
        return 0;
    }
    
    
    protected function _can_access_class($class = '')
    {
        // get user's group from session
        $user_groups = $this->session->userdata('groups');
        $user_group  = $user_groups[0];
        
        // get group
        $all_groups  = $this->config->item('groups');

        // print_debug($all_groups[$user_group]);
        if (array_key_exists($user_group, $all_groups) && array_key_exists('*', $all_groups[$user_group]))
        {
            return true;
        }
        else if (array_key_exists($user_group, $all_groups) && array_key_exists($class, $all_groups[$user_group]))
        {
            return true;
        }
        return false;
    }
    
    
    protected function _can_access_method_of_class($method = NULL, $class = NULL)
    {
        // get user's group from session
        $user_groups = $this->session->userdata('groups');
        $user_group  = $user_groups[0];
        
        // get group
        $all_groups  = $this->config->item('groups');

        if ( @$all_groups[$user_group]['*'] == '*'                  ||
             @$all_groups[$user_group][$class] == '*'               ||
             @in_array($method, array($all_groups[$user_group][$class])) 
        )
        {
            return true;
        }
        else if (@in_array('*', $all_groups[$user_group]['*']) || @in_array('*', $all_groups[$user_group][$class]))
        {
            return true;
        }
        else if (@in_array($method, $all_groups[$user_group][$class]))
        {
            return true;
        }
        return false;
    }
    
    /*    denied
     *
     *    If web user is denied access to a controller,
     *     this function displays the Denied view instead
     *     of the controller's view.
     */
    protected function _denied($method = NULL)
    {
        $class = $this->_this_class($this);
        $this->load->view($this->config->item('auth_denied'),array('message' => "You do not have access to $class/$method"));
    }
        
}



